home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
mint
/
editors
/
mjovesrc.zoo
/
recover.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-04-04
|
17KB
|
813 lines
/***************************************************************************
* This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne. JOVE *
* is provided to you without charge, and with no warranty. You may give *
* away copies of JOVE, including sources, provided that this notice is *
* included in all the files. *
***************************************************************************/
/* Recovers JOVE files after a system/editor crash.
Usage: recover [-d directory] [-syscrash]
The -syscrash option is specified in /etc/rc. It directs recover to
move all the jove tmp files from TMP_DIR (/tmp) to REC_DIR (/usr/preserve).
recover -syscrash must be invoked in /ect/rc BEFORE /tmp gets cleared out.
(about the same place as expreserve gets invoked to save ed/vi/ex files.
The -d option lets you specify the directory to search for tmp files when
the default isn't the right one.
Look in Makefile to change the default directories. */
#include <stdio.h> /* Do stdio first so it doesn't override OUR
definitions. */
#include "jove.h"
#include "temp.h"
#include "rec.h"
#include "rectune.h"
#include "wait.h"
#ifdef UNIX
# include <signal.h>
# include <sys/file.h>
# include <pwd.h>
# include <time.h>
#endif
#ifdef SYSV
# include <sys/utsname.h>
#endif
#ifndef L_SET
# define L_SET 0
# define L_INCR 1
#endif
extern char *ctime proto((const time_t *));
private char blk_buf[JBUFSIZ];
private int nleft;
private FILE *ptrs_fp;
private int data_fd;
private struct rec_head Header;
private long Nchars,
Nlines;
private char tty[] = "/dev/tty";
private int UserID,
Verbose = 0;
private char *Directory = NULL; /* the directory we're looking in */
private struct file_pair {
char *file_data,
*file_rec;
#define INSPECTED 01
int file_flags;
struct file_pair *file_next;
} *First = NULL;
private struct rec_entry *buflist[100]; /* system initializes to 0 */
#ifndef F_COMPLETION
# define F_COMPLETION /* since scandir.c is surrounded by an ifdef */
#endif
/* simpler version of one in util.c, needed by scandir.c */
UnivPtr
emalloc(size)
size_t size;
{
register UnivPtr ptr;
if ((ptr = malloc(size)) == NULL) {
fprintf(stderr, "couldn't malloc(%d)\n", size);
exit(1);
}
return ptr;
}
/* simpler version of one in util.c, needed by scandir.c */
UnivPtr
erealloc(ptr, size)
UnivPtr ptr;
size_t size;
{
if ((ptr = realloc(ptr, size)) == NULL) {
fprintf(stderr, "couldn't realloc(%d)\n", size);
exit(1);
}
return ptr;
}
/* duplicated in util.c, needed by scandir.c */
void
null_ncpy(to, from, n)
char *to,
*from;
size_t n;
{
(void) strncpy(to, from, n);
to[n] = '\0';
}
#define complain printf /* kludge! needed by scandir.c */
#include "scandir.c" /* to get dirent simulation and jscandir */
/* Get a line at `tl' in the tmp file into `buf' which should be LBSIZE
long. */
private char *getblock proto((daddr atl));
void
getline(tl, buf)
daddr tl;
char *buf;
{
register char *bp,
*lp;
register int nl;
lp = buf;
bp = getblock(tl >> 1);
nl = nleft;
tl = blk_round(tl);
while ((*lp++ = *bp++) != '\0') {
if (--nl == 0) {
tl = forward_block(tl);
bp = getblock(tl >> 1);
nl = nleft;
}
}
}
private char *
getblock(atl)
daddr atl;
{
int bno,
off;
static int curblock = -1;
bno = da_to_bno(atl);
off = da_to_off(atl);
nleft = JBUFSIZ - off;
if (bno != curblock) {
lseek(data_fd, (long) bno * JBUFSIZ, L_SET);
read(data_fd, (UnivPtr)blk_buf, (size_t)JBUFSIZ);
curblock = bno;
}
return blk_buf + off;
}
char *
copystr(s)
char *s;
{
char *str;
str = malloc((size_t) (strlen(s) + 1));
strcpy(str, s);
return str;
}
private char *CurDir;
/* Scan the DIRNAME directory for jove tmp files, and make a linked list
out of them. */
private int add_name proto((char *));
private void
get_files(dirname)
char *dirname;
{
struct direct **nmptr;
CurDir = dirname;
First = NULL;
jscandir(dirname, &nmptr, add_name,
(int (*) proto((UnivConstPtr, UnivConstPtr)))NULL);
}
private int
add_name(fname)
char *fname;
{
char dfile[128],
rfile[128];
struct file_pair *fp;
struct rec_head header;
int fd;
if (strncmp(fname, "jrec", (size_t)4) != 0)
return 0;
/* If we get here, we found a "recover" tmp file, so now
we look for the corresponding "data" tmp file. First,
though, we check to see whether there is anything in
the "recover" file. If it's 0 length, there's no point
in saving its name. */
(void) sprintf(rfile, "%s/%s", CurDir, fname);
(void) sprintf(dfile, "%s/jove%s", CurDir, fname + 4);
if ((fd = open(rfile, 0)) != -1) {
if ((read(fd, (UnivPtr) &header, sizeof header) != sizeof header)) {
close(fd);
return 0;
} else
close(fd);
}
if (access(dfile, 0) != 0) {
fprintf(stderr, "recover: can't find the data file for %s/%s\n", Directory, fname);
fprintf(stderr, "so deleting...\n");
(void) unlink(rfile);
(void) unlink(dfile);
return 0;
}
/* If we get here, we've found both files, so we put them
in the list. */
fp = (struct file_pair *) malloc (sizeof *fp);
if (fp == NULL) {
fprintf(stderr, "recover: cannot malloc for file_pair.\n");
exit(-1);
}
fp->file_data = copystr(dfile);
fp->file_rec = copystr(rfile);
fp->file_flags = 0;
fp->file_next = First;
First = fp;
return 1;
}
private void
options()
{
printf("Options are:\n");
printf(" ? list options.\n");
printf(" get get a buffer to a file.\n");
printf(" list list known buffers.\n");
printf(" print print a buffer to terminal.\n");
printf(" quit quit and delete jove tmp files.\n");
printf(" restore restore all buffers.\n");
}
/* Returns a legitimate buffer # */
private void tellme proto((char *, char *)),
list proto((void));
private struct rec_entry **
getsrc()
{
char name[128];
int number;
for (;;) {
tellme("Which buffer ('?' for list)? ", name);
if (name[0] == '?')
list();
else if (name[0] == '\0')
return NULL;
else if ((number = atoi(name)) > 0 && number <= Header.Nbuffers)
return &buflist[number];
else {
int i;
for (i = 1; i <= Header.Nbuffers; i++)
if (strcmp(buflist[i]->r_bname, name) == 0)
return &buflist[i];
printf("%s: unknown buffer.\n", name);
}
}
}
/* Get a destination file name. */
static char *
getdest()
{
static char filebuf[256];
tellme("Output file: ", filebuf);
if (filebuf[0] == '\0')
return NULL;
return filebuf;
}
#include "ctype.h"
private char *
readword(buf)
char *buf;
{
int c;
char *bp = buf;
do ; while (strchr(" \t\n", c = getchar()));
do {
if (strchr(" \t\n", c))
break;
*bp++ = c;
} while ((c = getchar()) != EOF);
*bp = '\0';
return buf;
}
private void
tellme(quest, answer)
char *quest,
*answer;
{
if (stdin->_cnt <= 0) {
printf("%s", quest);
fflush(stdout);
}
readword(answer);
}
/* Print the specified file to standard output. */
private jmp_buf int_env;
private SIGRESULT
catch(junk)
int junk;
{
longjmp(int_env, 1);
/*NOTREACHED*/
}
private void get proto((struct rec_entry **src, char *dest));
private void
restore()
{
register int i;
char tofile[100],
answer[30];
int nrecovered = 0;
for (i = 1; i <= Header.Nbuffers; i++) {
(void) sprintf(tofile, "#%s", buflist[i]->r_bname);
tryagain:
printf("Restoring %s to %s, okay?", buflist[i]->r_bname,
tofile);
tellme(" ", answer);
switch (answer[0]) {
case 'y':
break;
case 'n':
continue;
default:
tellme("What file should I use instead? ", tofile);
goto tryagain;
}
get(&buflist[i], tofile);
nrecovered += 1;
}
printf("Recovered %d buffers.\n", nrecovered);
}
private void dump_file proto((int which, FILE *out));
private void
get(src, dest)
struct rec_entry **src;
char *dest;
{
FILE *outfile;
if (src == NULL || dest == NULL)
return;
(void) signal(SIGINT, catch);
if (setjmp(int_env) == 0) {
if (dest == tty)
outfile = stdout;
else {
if ((outfile = fopen(dest, "w")) == NULL) {
printf("recover: cannot create %s.\n", dest);
(void) signal(SIGINT, SIG_DFL);
return;
}
printf("\"%s\"", dest);
}
dump_file(src - buflist, outfile);
} else
printf("\nAborted!\